package pub.tbc.api.handler;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.*;
import lombok.extern.slf4j.Slf4j;
import pub.tbc.toolkit.core.EmptyUtil;
import pub.tbc.toolkit.core.collect.Lists;

import java.io.UnsupportedEncodingException;
import java.util.List;

import static io.netty.handler.codec.http.HttpHeaderNames.*;
import static io.netty.handler.codec.http.HttpResponseStatus.METHOD_NOT_ALLOWED;


/**
 * http请求过滤：限制HttpMethod、ContentType
 *
 * @author tbc on 2017/3/18.
 */
@Slf4j
public class HttpMethodFilterHandler extends AbstractHttpInboundHandler {
    private final HttpVersion HTTP_VERSION = HttpVersion.HTTP_1_1;
    private final HttpResponseStatus RESP_STATUS = METHOD_NOT_ALLOWED;
    private final String ERR_MSG = "不被支持的HTTP方法，系统仅支持：GET,POST,PUT,DELETE\r\n";


    // 默认接受的HTTP方法白名单
    private final List<HttpMethod> DEFAULT_METHOD_WHITE_LIST = Lists.newArrayList(
            HttpMethod.GET,
            HttpMethod.POST,
            HttpMethod.DELETE,
            HttpMethod.PUT
    );


    private void sendErr(ChannelHandlerContext context, FullHttpRequest request) throws UnsupportedEncodingException {
        System.out.println("filter : " + request.method());
        System.out.println("filter : " + request.uri());

        FullHttpResponse response = new DefaultFullHttpResponse(
                HTTP_VERSION,
                METHOD_NOT_ALLOWED,
                Unpooled.wrappedBuffer(ERR_MSG.getBytes("UTF-8"))
        );
        response.headers().set(CONTENT_TYPE, "text/plain").set(CONTENT_LENGTH, response.content().readableBytes());
        if (HttpUtil.isKeepAlive(request)) {
            response.headers().set(CONNECTION, HttpHeaderValues.KEEP_ALIVE);
        }
        ChannelFuture future = context.writeAndFlush(response);

        if (!HttpUtil.isKeepAlive(request)) {
            future.addListener(ChannelFutureListener.CLOSE);
        }
    }


    /**
     * 是否有请求体
     *
     * @param request 请求对象
     * @return boolean
     */
    private boolean isContent(FullHttpRequest request) {
        // get和delete方法无请求体
        String method = request.method().name();

        HttpHeaders headers = request.headers();


        return false;
    }

    private void next(ChannelHandlerContext ctx, FullHttpRequest request) {
        ctx.fireChannelRead(request);
    }

    /**
     * 判断http请求的contentType是否为
     *
     * @param context ChannelHandlerContext
     * @param request FullHttpRequest
     * @throws Exception .
     */
    @Override
    protected void channelRead0(ChannelHandlerContext context, FullHttpRequest request) throws Exception {
        if (EmptyUtil.isEmpty(request))
            throw new RuntimeException("请求无效或者解码失败！");

        //
        if (isContent(request)) {
            next(context, request);
        }

        // 读取配置，设置方法白名单，默认四大方法
        List<HttpMethod> whiteList = DEFAULT_METHOD_WHITE_LIST;
        HttpMethod httpMethod = request.method();

        if (whiteList.contains(httpMethod)) {
            context.fireChannelRead(request);
        } else {
            sendErr(context, request);
        }


    }
}
